#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <pthread.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <signal.h>
#include <sys/wait.h>
#include "wrap.h"

void catch_child(int signum ){
    while(waitpid(0,NULL,WNOHANG)>0){ //0表示无差别回收,一次只回收一个
    }
    return ;
}

int main(){
    struct sockaddr_in server_sockaddr;

    //memset(&server_scokaddr,0,sizeof(server_sockaddr)); //将结构地址清0
    bzero(&server_sockaddr,sizeof(server_sockaddr));

    int s_fd = Socket(AF_INET, SOCK_STREAM, 0);
    server_sockaddr.sin_family = AF_INET;//IPv4
    server_sockaddr.sin_port = htons(7777);//端口
    server_sockaddr.sin_addr.s_addr = INADDR_ANY;//本主机的任意IP都可以使用
    bzero(&(server_sockaddr.sin_zero),8);//填充0


    Bind(s_fd,(struct sockaddr *)&server_sockaddr,sizeof(struct sockaddr));
    printf("bind success!\n");

    Listen(s_fd,5);
    printf("listen success!\n");
    struct sockaddr_in client_sockaddr;
    socklen_t client_sockaddr_len = sizeof(client_sockaddr);
    pid_t pid;
    int c_fd;
    while(1){
        c_fd = Accept(s_fd,(struct sockaddr *)&client_sockaddr,&client_sockaddr_len);
        printf("accept success!\n");
        char client_ip[1024];
        printf("client ip :%s port %d\n",inet_ntop(AF_INET,&client_sockaddr.sin_addr.s_addr,client_ip,sizeof(client_ip)),ntohs(client_sockaddr.sin_port));

        pid = fork();
        if (pid < 0){
            perr_exit("fork error");
        }else if(pid == 0){
            Close(s_fd);
            break;
        }else{
            struct sigaction act;
            act.sa_handler = catch_child;
            sigemptyset(&act.sa_mask);
            act.sa_flags = 0;
            int ret = sigaction(SIGCHLD,&act,NULL);//注册信号捕捉函数
            if (ret != 0){
                perr_exit("sigaction error");
            }
            Close(c_fd);
        }

    }
    if(pid == 0){//子进程逻辑
        for(;;){
            char buf[1024];
            int ret = Read(c_fd,buf,sizeof(buf));
            if(ret == 0){
                Close(c_fd);
                exit(1);
            }
            write(STDOUT_FILENO,buf,ret);
            int i = 0;
            for(;i<ret;i++){
                buf[i] = toupper(buf[i]);
            }
            write(c_fd,buf,ret);
        }
    }
    return 0;
}